/*************************************************************************
 *                                                                       *
 * This file is part of the FreeMAPs distribution.  For full copyright   *
 * information, see COPYRIGHT and COPYING.LESSER.                        *
 *                                                                       *
 * Author:           sqbang                                              *
 * Email:            sqbang@ustc.edu                                     *
 * Date:             2011.09.25                                          *
 *                                                                       *
 *************************************************************************/

//declaration header
#include "COMMON/bdry/IrregularBoundaryConditions.h"

//COMMON headers
#include "COMMON/bdry/IrregularBoundaryConditionStrategy.h"
#include "COMMON/equa/PDEEquationEnsembleStrategy.h"
#include "COMMON/equa/EquationDomain.h"
#include "COMMON/tbox/LogMessage.h"

#include <iostream>


namespace FreeMAPs
{

IrregularBoundaryConditions::IrregularBoundaryConditions (
    const std::string& parent_name,
    const std::string& object_name):
    Parent (parent_name, object_name, false)
{}



IrregularBoundaryConditions::~IrregularBoundaryConditions()
{
    this->clear();
}



void
IrregularBoundaryConditions::clear()
{
    Utilities::clear_pointer_object (d_bdry_conds);
}


void
IrregularBoundaryConditions::get_from_input (
    const InputDatabase* db,
    const PDEEquationEnsembleStrategy* equation_ensemble)
{
    this->prepare_for_use (db);

    db->insert_allowable_key_with_items ("bc_names");
    db->check_allowable_keys ();


    if (db->key_exists ("bc_names") && db->is_string("bc_names"))
    {
        const std::vector<std::string>& bc_names = db->get_string_vector ("bc_names");

        for (std::size_t pos = 0; pos < bc_names.size(); ++pos)
        {
            const std::string& bc_name = bc_names[pos];


            if (db->key_exists (bc_name) && db->is_database(bc_name))
            {
                db->check_requisite_key (bc_name, DataType::DATABASE, false, false);

                const BoundaryConditionType bc_type = db->get_enum_from_subdatabase<BoundaryConditionType>(bc_name, "bc_type");

                //std::cout << __FILE__ << __LINE__ << " bc_type = " << FreeMAPs::Utilities::enum_to_string<BoundaryConditionType>(bc_type) << std::endl;
                IrregularBoundaryConditionStrategy* bc = IrregularBoundaryConditionStrategy::create_object (
                            bc_type,
                            this->get_full_name(),
                            bc_name,
                            equation_ensemble);

                bc->get_from_input (db->get_database (bc_name));

                d_bdry_conds.insert (std::make_pair (bc_name, bc));
            }
        }
    }
}



std::ostream&
operator << (
    std::ostream& os,
    const IrregularBoundaryConditions& rhs)
{
    os << "irregular_boundary_conditions\n{\n";

    os << LogMessage::get_log_info_from_map_keys(
           "bc_names",
           rhs.d_bdry_conds,
           ONE_TAB,
           true) << '\n';

    std::ostringstream oss;
    for (IrregularBoundaryConditions::const_iterator pb = rhs.d_bdry_conds.begin();
            pb != rhs.d_bdry_conds.end(); ++pb)
    {
        os << '\n' << LogMessage::get_prefix (ONE_TAB) << pb->second->get_bc_name() << '\n';
        os << LogMessage::get_prefix (ONE_TAB) << "{\n";
        oss.str ("");
        oss << *(pb->second);
        os << LogMessage::get_log_info (oss, TWO_TAB) << '\n';
        os << LogMessage::get_prefix (ONE_TAB) << "}\n";
    }

    os << "}";

    return os;
}

} // namespace FreeMAPs
